﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Csla.DataPortalClient;
using Csla.Server;
using OpenExpressApp.Library.DogSensor;

namespace OpenExpressApp.Host.WPF
{
    public class DogWCFProxy : IDataPortalProxy
    {
        private WcfProxy _innerProxy;

        public DogWCFProxy()
        {
            this._innerProxy = new WcfProxy();
        }

        #region IDataPortalProxy Members

        public bool IsServerRemote
        {
            get
            {
                return this._innerProxy.IsServerRemote;
            }
        }

        #endregion

        #region IDataPortalServer Members

        public DataPortalResult Create(Type objectType, object criteria, DataPortalContext context)
        {
            this.CheckDogOpened(context);

            return this._innerProxy.Create(objectType, criteria, context);
        }

        public DataPortalResult Delete(Type objectType, object criteria, DataPortalContext context)
        {
            this.CheckDogOpened(context);

            return this._innerProxy.Delete(objectType, criteria, context);
        }

        public DataPortalResult Fetch(Type objectType, object criteria, DataPortalContext context)
        {
            this.CheckDogOpened(context);

            return this._innerProxy.Fetch(objectType, criteria, context);
        }

        public DataPortalResult Update(object obj, DataPortalContext context)
        {
            this.CheckDogOpened(context);

            return this._innerProxy.Update(obj, context);
        }

        #endregion

        private void CheckDogOpened(DataPortalContext context)
        {
            if (NeedCheck())
            {
                DogSensorCommand command = new DogSensorCommand();

                command = this._innerProxy.Update(command, context).ReturnObject as DogSensorCommand;
                //command = DataPortal.Execute(command);
                if (command.Opend == false)
                {
                    throw new Exception("加密锁没有开启。");
                }
            }
        }

        private static DateTime _timeChecked = default(DateTime);

        /// <summary>
        /// 两次dog检测之间的最少时间（分钟）。
        /// </summary>
        private static readonly int CHECK_SPAN_MINUTES = 2;

        /// <summary>
        /// 返回是否需要检测Dog。
        /// 
        /// 由于每次都检测的话，效率会比较慢，
        /// 所以这里设置为，如果上次检测到现在为止，如果超过固定的时间才需要再次检测。
        /// </summary>
        /// <returns></returns>
        private bool NeedCheck()
        {
            bool result = false;

            if (_timeChecked == default(DateTime))
            {
                result = true;
            }
            else
            {
                var ts = DateTime.Now - _timeChecked;
                if (ts.TotalMinutes > CHECK_SPAN_MINUTES)
                {
                    result = true;
                }
            }

            if (result)
            {
                _timeChecked = DateTime.Now;
            }

            return result;
        }
    }
}